<?php


/**
* Biere
*/
class Biere
{ 
  private $no;
  private $nom;
  private $pays;
  private $type;
  private $brasserie;
  private $fermentation;
  private $saveur;
  private $descriptif;
  private $image;
  private $alcool;
  private $notes = array();
  private $commentaires = array();

  public static $totalBieres = 0;

  /**
   * Constructeur
   * @param array $config attributs 
   */
  function __construct( $config = array() )
  {
    foreach( $config as $key => $value )
      $this->{$key} = property_exists( get_class($this), $key) ? $value : null;   
  }

  /**
   * [getList description]
   * @param  [type] $fileName [description]
   * @return [type]           Retourne un array contenant les informations des fermentations
   */
  static function getList( $filePath, 
                           $listes = array( 'degres' => array(), 
                                            'types' => array(),
                                            'pays' => array() ), 
                           $params = array(),
                           $biereSansImageComprise = true)
  {
    $currentBeer = 0;

    // Modele permettant de recuperer un tableau associatif les liste de notes de chaque bieres en fonction de leur id;
    $noteModel = new Note();
    $notes = $noteModel->getNotes();

    $commentaireModel = new Commentaire();
    $commentaires = $commentaireModel->getCommentaires();

    // Chargement du fichier xml $filePath contenant les bieres
    $document = new DOMDocument;
    $document->load($filePath);

    // Liste DOMElement de toutes les bieres 
    $xmlBieres = $document->getElementsByTagName( 'biere' );

    // Declaration de la liste de biere;
    $listeBiere = array();

    // Parcours de la liste DOMElement des bieres
    foreach( $xmlBieres as $xmlBiere )
    {
      // Recuperation des informations des bieres à partir des objets DOMElement
      // Pour les informations qui sont sous forme d'objet (pays, type, fermentation),
      // On recupere leur ID via leurs modeles avec la methode 'getByAttribute'
      $attributs = array(
        'no' => $xmlBiere->getAttribute('id'),
        'nom' => $xmlBiere->getElementsByTagName('nom')->item(0)->nodeValue,
        'brasserie' => $xmlBiere->getElementsByTagName('brasserie')->item(0)->nodeValue,
        'descriptif' => $xmlBiere->getElementsByTagName('descriptif')->item(0)->nodeValue,
        'image' => $xmlBiere->getElementsByTagName('image')->item(0)->nodeValue,
        'alcool' => $xmlBiere->getElementsByTagName('alcool')->item(0)->nodeValue,
        'pays' => Pays::getByAttribute($listes['pays'], 'no', $xmlBiere->getElementsByTagName('pays')->item(0)->nodeValue),
        'type' => TypeBiere::getByAttribute($listes['types'], 'no', $xmlBiere->getElementsByTagName('type')->item(0)->nodeValue),
        'fermentation' => DegreFermentation::getByAttribute($listes['degres'], 'no', $xmlBiere->getElementsByTagName('fermentation')->item(0)->nodeValue),
      );

      // Instanciation de notre biere grâce au attributs
      $biere = new Biere($attributs);


      // Si la variable biere biereSansImageComprise est fause, on récupère uniquement les bières avec photos
      if(!$biereSansImageComprise && $biere->get('image') == 'asset/img/bieres/no-photo.jpg')
        continue;

      // Conditions l'enregistrement de la biere dans la liste
      // Les conditions sont définies dans $params
      if(!empty($params))
      {
        // Présence de contition en fonction du type, si le type ne correspond pas, on ne l'ajoute pas dans le liste
        if(isset($params['type']) && $params['type'] != null && $biere->get('type')->get('no') != $params['type'])
          continue;

        // Présence de contition en fonction du degre, si le degre ne correspond pas, on ne l'ajoute pas dans le liste
        if(isset($params['degre']) && $params['degre'] != null && $biere->get('fermentation')->get('no') != $params['degre'])
          continue;

        // Présence de contition en fonction du pays, si le pays ne correspond pas, on ne l'ajoute pas dans le liste
        if(isset($params['pays']) && $params['pays'] != null && $biere->get('pays')->get('no') != $params['pays'])
          continue;

        // Recherche par chaine
        // On va rechercher la présence de la chaine dans l'ensemble des attributs de la biere
        // En cas de présence dans un attribut, on ajoute la biere à la liste
        $params['chaine'] = strtolower($params['chaine']);

        if(isset($params['chaine']) && $params['chaine'] != null) {
          $trouve = false;
          if (strpos(strtolower($biere->get('nom')), $params['chaine']) !== false) {
            $trouve = true;
          }
          if (strpos(strtolower($biere->get('brasserie')), $params['chaine']) !== false) {
            $trouve = true;
          }
          if (strpos(strtolower($biere->get('descriptif')), $params['chaine']) !== false) {
            $trouve = true;
          }
          if (strpos(strtolower($biere->get('note')), $params['chaine']) !== false) {
            $trouve = true;
          }
          if (strpos(strtolower($biere->get('alcool')), $params['chaine']) !== false) {
            $trouve = true;
          }
          if (strpos(strtolower($biere->get('type')->get('type')), $params['chaine']) !== false) {
            $trouve = true;
          }
          if (strpos(strtolower($biere->get('fermentation')->get('degre')), $params['chaine']) !== false) {
            $trouve = true;
          }

          if(!$trouve)
            continue;
        }
      }

      // En cas d'existance de notes pour cette biere on les ajoute en attribut
      if(isset($notes[$biere->get('no')]))
        $biere->set('notes', $notes[$biere->get('no')]);

      // En cas d'existance de notes pour cette biere on les ajoute en attribut
      if(isset($commentaires[$biere->get('no')]))
        $biere->set('commentaires', $commentaires[$biere->get('no')]);


      if(isset($params['intervale']) && is_array($params['intervale']))
      {
        if($params['intervale'][0] < $currentBeer && $params['intervale'][1] >= $currentBeer)
          array_push( $listeBiere, $biere ); 
      } else
      {
        // Ajout de la biere à la liste
        array_push( $listeBiere, $biere ); 
      }

      $currentBeer++;
      
      Biere::$totalBieres++;
    }

    return $listeBiere;
  }

  /**
   * [getList description]
   * @param  [type] $fileName [description]
   * @return [type]           Retourne un array contenant les informations des fermentations
   */
  static function getListWithPagination( $filePath, 
                           $listes = array( 'degres' => array(), 
                                            'types' => array(),
                                            'pays' => array() ), 
                           $params = array(),
                           $biereSansImageComprise = true)
  {
    // Calcul de l'intervale de recherche en fonction de la page courante et du nombre par page
    if(isset($params['page']) && isset($params['nbParPage']))
    {
      $params['intervale'] = array($params["page"] * $params["nbParPage"] - 1, $params["page"] * $params["nbParPage"] + $params["nbParPage"] - 1);
    }  
    $liste = Biere::getList($filePath, $listes, $params, $biereSansImageComprise);

    return array('pagination' => Pagination::getPagination(Biere::$totalBieres, $params['page'] + 1, $params['nbParPage']), 'liste' => $liste);
  }

  /**
   * [saveImageToFolder Recupere une image grace à son lien et l'enregistre dans le dossier /asset/img/biere]
   * @param  String $name 
   * @return [type]       [description]
   */
  function saveImageToFolder($name)
  {
    if($this->image == "http://www.guidedesbieres.com/type/../photos/no-photo.jpg") {
      $this->image = "asset/img/bieres/no-photo.jpg";
    } else {
      file_put_contents("asset/img/bieres/" . $name . ".jpg", file_get_contents($this->image));
      $this->image = "asset/img/bieres/" . $name . ".jpg";
    }
  }

  /**
   * Retourne l'objet si l'élément $attribut == $valeur est présent dans $liste
   * Retourne null si l'objet n'est pas présent
   * @param  [type] $listeDegres [description]
   * @param  [type] $attribute   [description]
   * @param  [type] $value       [description]
   * @return [type]              [description]
   */
  static function getByAttribute( $liste, $attribut, $valeur)
  {
    foreach ($liste as $key => $degre) {
      if($degre->get($attribut) == $valeur)
        return $degre;
    }
    return null;
  }

  /**
   * Enregistre l'instance courante dans le fichier spécifier
   */
  function exportToFile( $name )
  {
    $doc = new DOMDocument( '1.0' );
    $doc->preserveWhiteSpace = false;
    $doc->formatOutput = true;

    if (file_exists($name)) {
      $doc->load($name);
      $root = $doc->getElementsByTagName( 'basedonneebieres' )->item(0);
      $idBiere = $root->getElementsByTagName('biere')->length;
    } else {
      $root = $doc->createElement( 'basedonneebieres' );
      
      $idBiere = 0;
    }
    
    $doc->appendChild( $root );

    $this->saveImageToFolder($idBiere);

    $biereDoc = $doc->createElement( 'biere' );

    $biereDoc->setAttribute('id', $idBiere);

    $nom = $doc->createElement( 'nom' );
    $nom->appendChild($doc->createTextNode($this->get('nom')));

    $pays = $doc->createElement( 'pays' );
    $pays->appendChild($doc->createTextNode($this->get('pays')->get('no')));

    $type = $doc->createElement( 'type' );
    $type->appendChild($doc->createTextNode($this->get('type')->get('no')));

    $brasserie = $doc->createElement( 'brasserie' );
    $brasserie->appendChild($doc->createTextNode($this->get('brasserie')));

    $fermentation = $doc->createElement( 'fermentation' );
    $fermentation->appendChild($doc->createTextNode($this->get('fermentation')->get('no')));

    $descriptif = $doc->createElement( 'descriptif' );
    $descriptif->appendChild($doc->createTextNode($this->get('descriptif')));

    $note = $doc->createElement( 'note' );
    $note->appendChild($doc->createTextNode($this->get('note')));

    $image = $doc->createElement( 'image' );
    $image->appendChild($doc->createTextNode($this->get('image')));

    $alcool = $doc->createElement( 'alcool' );
    $alcool->appendChild($doc->createTextNode($this->get('alcool')));

    $biereDoc->appendChild($nom);
    $biereDoc->appendChild($pays);
    $biereDoc->appendChild($type);
    $biereDoc->appendChild($brasserie);
    $biereDoc->appendChild($fermentation);
    // $biereDoc->appendChild($saveur);
    $biereDoc->appendChild($descriptif);
    $biereDoc->appendChild($note);
    $biereDoc->appendChild($image);
    $biereDoc->appendChild($alcool);

    $root->appendChild($biereDoc);

    $doc->save($name);

    return $doc;
  }

  /**
   * Retourne le nombre de note
   */
  public function getNombreDeNotes()
  {
    return count($this->notes);
  }

  public function getNotation( $nbDecimales = 2 )
  {
    return $this->getNombreDeNotes() != 0 ? round(array_sum($this->notes) / $this->getNombreDeNotes(), $nbDecimales) : 0;
  }

  /**
   * Accesseurs
   * @param  [type] $key [description]
   * @return [type]      [description]
   */
  public function get( $key )
  {
    if ( property_exists( get_class($this), $key ) )
      return $this->{$key};
    else
      return null;
  }

  public function set( $key, $value )
  {
    if ( property_exists( get_class( $this ), $key ) )
      $this->{$key} = $value;
  }
}

?>